using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using BlimpControlPanel;
using System.Collections;
using System.Diagnostics;

namespace NMEAConverter
{
   public partial class NMEAConverter : Form
   {
      ArrayList latLongAltArray;

      public NMEAConverter()
      {
         InitializeComponent();
         latLongAltArray = new ArrayList();

      }

      private void btnBrowseNMEAData_Click(object sender, EventArgs e)
      {
         OpenFileDialog ofd = new OpenFileDialog();

         ofd.InitialDirectory = @"C:\Documents and Settings\mellej\My Documents\My Dropbox\Oakland University\ECE 594 (S09)\Google Earth Data\GPS Data";
         ofd.DefaultExt       = "*.txt";
         ofd.Filter           = "Text (*.txt)|*.txt|All Files (*.*)|*.*";
         ofd.RestoreDirectory = true;
         ofd.AddExtension     = true;

         DialogResult dr = ofd.ShowDialog();

         if (dr == DialogResult.OK)
            tbNMEAFilename.Text = ofd.FileName;
      }

      private void btnBrowseKmlFile_Click(object sender, EventArgs e)
      {
         SaveFileDialog sfd   = new SaveFileDialog();
         sfd.Filter           = "KML File(*.kml)|*.kml|All Files (*.*)|*.*";
         sfd.FileName         = "test.kml";
         sfd.InitialDirectory = @"C:\Documents and Settings\mellej\My Documents\My Dropbox\Oakland University\ECE 594 (S09)\Google Earth Data\GPS Data";

         if (sfd.ShowDialog(this) == DialogResult.OK)
            tbKMLFilename.Text = sfd.FileName;
      }

      private void btnConvert_Click(object sender, EventArgs e)
      {
         if (!File.Exists(tbNMEAFilename.Text))
            return;

         StreamReader sr = new StreamReader(new FileStream(tbNMEAFilename.Text, FileMode.Open));

         string dataLine = "";
         bool dataValid = false;

         while (!sr.EndOfStream)
         {
            dataLine = sr.ReadLine();

            if (dataValid)
               ParseDataLine(dataLine.Split(','));
            else if (dataLine.StartsWith("$GPGSA"))
               dataValid = ParseGPGSAMessage(dataLine, dataValid);
         }

         sr.Close();

         xmlParsing parser = new xmlParsing();
         parser.saveKMLData(tbKMLFilename.Text, tbPathname.Text, latLongAltArray, new ProgressBar(), false);
         MessageBox.Show(this, "Conversion Complete", "Complete", MessageBoxButtons.OK, MessageBoxIcon.Information);
      }

      private bool ParseGPGSAMessage(string dataLine, bool dataValid)
      {
         string[] data = dataLine.Split(',');

         if (data.Length == 18)
         {
            if (data[2] == "2" || data[2] == "3")
               return true;
            else
               return false;
         }

         return dataValid;
      }

      private void ParseDataLine(string[] dataLine)
      {
         //if (dataLine[0] == "$GPRMC" && dataLine.Length == 13)
         //{
         //    if(dataLine[2] != "A")
         //        return;

         //    Utilities utils = new Utilities();
         //    double [] data = utils.ConverStringsToData(dataLine);

         //    latLongAltArray.Add(utils.FormatDate(dataLine[9]) + ", " + utils.FormatTime(dataLine[1]) + ", " +
         //        ConvertLongitude(dataLine[5]) + ", " + ConvertLatitude(dataLine[3]) + ", " + 1000);
         //}
         if (dataLine[0] == "$GPGGA" && dataLine.Length == 15 && CheckSumValid(dataLine))
         {
            Utilities utils = new Utilities();

            latLongAltArray.Add(utils.FormatDate(dataLine[9]) + ", " + utils.FormatTime(dataLine[1]) + ", " +
                ConvertLongitude(dataLine[4], dataLine[5]) + ", " + ConvertLatitude(dataLine[2], dataLine[3]) + ", " +
                utils.ConvertMetersToFeet(dataLine[9]));
         }
      }

      private bool CheckSumValid(string[] dataLine)
      {
         byte CS = 0;
         string sentCS = "";

         foreach (string data in dataLine)
         {
            for (int i = 0; i < data.Length; i++)
            {
               if (data.ToCharArray()[i] == '$')
                  continue;
               else if (data.ToCharArray()[i] == '*')
               {
                  i++;

                  for (; i < data.Length; i++)
                     sentCS += data.ToCharArray()[i].ToString();

                  break;
               }

               CS ^= (byte)data.ToCharArray()[i];
            }
         }

         int sentCSInt = 0;

         bool parseOK = int.TryParse(sentCS, System.Globalization.NumberStyles.HexNumber, null, out sentCSInt);
         bool valid = (CS == sentCSInt);
         return valid && parseOK;
      }


      private static string ConvertLatitude(string latitude, string northSouth)
      {
         char[] charData = latitude.ToCharArray();
         string hours = charData[0].ToString() + charData[1].ToString();
         string minutes = "";

         for (int x = 2; x < charData.Length; x++)
            minutes += charData[x].ToString();

         return (northSouth == "S" ? "-" : "") + GetHoursString(hours, minutes);
      }

      private static string ConvertLongitude(string logitude, string eastWest)
      {
         char[] charData = logitude.ToCharArray();
         string hours = charData[0].ToString() + charData[1].ToString() + charData[2].ToString();
         string minutes = "";

         for (int x = 3; x < charData.Length; x++)
            minutes += charData[x].ToString();

         return (eastWest == "W" ? "-" : "") + GetHoursString(hours, minutes);
      }

      private static string GetHoursString(string hours, string minutes)
      {
         double dbMinutes = 0;

         if (double.TryParse(minutes, out dbMinutes))
            dbMinutes = dbMinutes / 60;

         double dbHours = 0;

         if (double.TryParse(hours, out dbHours))
            dbHours = dbHours + dbMinutes;

         return dbHours.ToString();
      }

      private void btnViewInGE_Click(object sender, EventArgs e)
      {
         if (tbKMLFilename.Text.Length > 0 && File.Exists(tbKMLFilename.Text))
         {
            Process new_proc = null;

            ProcessStartInfo start_info = new ProcessStartInfo(tbKMLFilename.Text);
            start_info.ErrorDialog = false;
            new_proc = new Process();

            new_proc.StartInfo = start_info;
            new_proc.Start();
         }
      }

      private void btnCancel_Click(object sender, EventArgs e)
      {
         this.Close();
      }
   }
}